#pragma once

//#include "World Includes.h"
#include "World Definitions.h"
#include "../Global References/VectorContainer.h"
#include "Block.h"
#include "World Tools.h"
#include "Extra Container Types.h"

//Basic test of loading a chunk
// _Chunk C(BASE_CHUNK_LOAD_PATH,new Block[CHUNK_HEIGHT * CHUNK_WIDTH],0,CHUNK_HEIGHT,CHUNK_WIDTH);
class _Chunk
{
private:
	char * FileName;
	//The grid is never allocated by the chunk
	// its handed a data slot to store its information and then it
	// nulls it out once its unloaded
	Block * Grid;

	// FUTURE TODO BY: add AI path vector

	int BiomeIndex;

	short X,Y;
	short H,W;

	Vector<WorldChange*> * ChunkChanges;
	bool Changed;
public:
	_Chunk() : Grid(NULL),
			  BiomeIndex(0) ,
			  FileName(NULL),
			  X(0),
			  Y(0),
			  H(CHUNK_HEIGHT),
			  W(CHUNK_WIDTH),
			  Changed(false)
	{}

	~_Chunk() {
		Grid = NULL;
		delete FileName;
		WorldChange * ToDelete;
		while(ChunkChanges->size()) {
			ToDelete = ChunkChanges->getByIndex(0);
			ChunkChanges->remove(0);
			delete ToDelete;
		}
		delete ChunkChanges;
	}

	//This will setup the chunk the first time
	// Setting the file name and its position in relation to the world.
	// As well as initializing all of its base values
	int Setup(char * a_File, Block * a_G,int a_X,int a_Y, int a_H, int a_W);

	//Saves the data and then cleans up the class so it no longer takes up a lot of memory
	int Unload();
	int Save();

	int Clear();

	//Sets all the values to the new data
	int Load(Block * pBlockGrid);

	//Files write from bottom right to top left of the chunk - Visualization explanation
	//Files write to the chunk with x and y starting at max and start counting down - Integer explanation
	int LoadGridFromFile(char * F);
	//Loads with the filename it has stored
	int LoadGridFromFile();

	//Returns true if the chunk is currently loaded into memory
	bool IsLoaded() {if(Grid != NULL) return true; else return false;}
	
	//Is called when a change is executed
	void Change() { Changed = true; }

	void Saved() { Changed = false; }

	//If it needs to be saved or not
	bool NeedSave() { return Changed; }

	//Saves with the filename it has stored
	int const SaveGridToFile();
	int SaveGridToFile(char * F);
	
	Block * Access() { return Grid; }
	inline int const SetGrid(Block * a_G) {Grid = a_G;return SUCCEED;}

	inline char const * getFileName() const {return FileName;}

	inline const short GetX() const { return X; }
	inline const short GetY() const { return Y; }
	inline const short GetPosModX() const { return X * W * BLOCK_TEXTURE_SIZE; }
	inline const short GetPosModY() const { return Y * H * BLOCK_TEXTURE_SIZE; }
	inline const short GetHeight() const { return H; }
	inline const short GetWidth() const { return W; }


	//The following functions handle any changes that need to be done to a chunk
	inline const short GetChangesLeft() const { return ChunkChanges->size(); } const
	inline void AddChange(WorldChange * WC) {
		ChunkChanges->push(WC);
	}
	inline void ClearChanges() { ChunkChanges->clear(); }
	void FinishAllChanges();
	bool FinishOldestChange();

	//Biome Functions
	void SetBiome(int const & BI) {
		BiomeIndex = BI;
	}
	inline int GetBiome() {return BiomeIndex;}
};